const Util = require("./util");

const AjjlDatas = {
    /**
     * 获取按键精灵函数信息
     *
     * @param {RegExp} functionReg 获取函数的正则表达式
     * @param {String} content 获取来源的长字符
     * @returns {Array} [{name: functionName, type: functionType, params: [param1, param2...]}]]
     */
    getAjjlFunctionInfoList(functionReg, content) {
        let resultFunctionInfoList = [];
        let functionInfoList = content.match(functionReg);
        functionInfoList.forEach((functionInfo) => {
            let functionType = functionInfo.substring(0, functionInfo.indexOf(" "));
            let functionName = functionInfo.substring(functionInfo.indexOf(" ") + 1, functionInfo.indexOf("("));
            let functionParamStr = functionInfo.substring(functionInfo.indexOf("(") + 1, functionInfo.indexOf(")"));
            let functionParams = functionParamStr.replace(/ /g, "").split(",");
            resultFunctionInfoList.push({ name: functionName, type: functionType, params: functionParams });
        });
        return resultFunctionInfoList;
    },
    /**
     * 获取按键精灵文件信息
     *
     * @param {String} filesPath 文件夹/文件路径
     * @param {String} postfix 文件后缀名
     * @param {Boolean} intoSubFolder 是否进入子文件夹
     * @returns {Array} [{class, path, content, infos}]
     */
    getAjjlFilesInfoList(filesPath, postfix, intoSubFolder) {
        let ajjlFunctionInfoList = [];
        let ajjlFileInfoList = Util.getFilesInfoList(filesPath, postfix, intoSubFolder);
        ajjlFileInfoList.forEach((ajjlFileInfoObj) => {
            let content = Util.readFile(ajjlFileInfoObj["path"], "GBK");
            let functionInfoList = this.getAjjlFunctionInfoList(/(Function|Sub)\s*\S*\(.*\)/g, content);
            ajjlFunctionInfoList.push({
                class: ajjlFileInfoObj["name"],
                postfix: postfix,
                path: ajjlFileInfoObj["path"],
                content: content,
                infos: functionInfoList,
            });
        });
        return ajjlFunctionInfoList;
    },
    /**
     * 获取按键精灵命令信息
     *
     * @returns {Array} [{name, format, description, case}]
     */
    getAjjlCommandInfoList() {
        // 创建命令文件
        let content = Util.readFile("D:\\Program Files (x86)\\按键精灵\\按键精灵2014\\doc\\command.ini", "GBK");
        let commandInfoStrList = content.split("\n");
        // 提取命令
        let commandInfoList = [];
        let curKeyInfo = new Array(4);
        for (let row = 0; row < commandInfoStrList.length - 1; row++) {
            let isOverCommand = false;
            const rowStr = commandInfoStrList[row];
            if (rowStr.startsWith("[")) {
                curKeyInfo[0] = Util.trimString(rowStr.substring(1, rowStr.indexOf("]")));
            } else if (rowStr.startsWith("格式：")) {
                let formatList = Util.getStringFormRowToStr(commandInfoStrList, row, "解释：");
                curKeyInfo[1] = Util.trimString(formatList[0].substring(3, formatList[0].length));
                row = formatList[1];
            } else if (rowStr.startsWith("解释：")) {
                let descriptionList = Util.getStringFormRowToStr(commandInfoStrList, row, "举例：");
                let descriptionList2 = Util.getStringFormRowToStr(commandInfoStrList, row, "[");
                if (descriptionList[0].length > descriptionList2[0].length || descriptionList[0].length === descriptionList2[0].length) {
                    descriptionList = descriptionList2;
                    isOverCommand = true;
                }
                row = descriptionList[1];
                curKeyInfo[2] = Util.trimString(descriptionList[0].substring(3, descriptionList[0].length));
            } else if (rowStr.startsWith("举例：")) {
                let caseList = Util.getStringFormRowToStr(commandInfoStrList, row, "[");
                curKeyInfo[3] = Util.trimString(caseList[0].substring(3, caseList[0].length));
                row = caseList[1];
                isOverCommand = true;
            }
            if (isOverCommand) {
                commandInfoList.push({ name: curKeyInfo[0], format: curKeyInfo[1], description: curKeyInfo[2], case: curKeyInfo[3] });
                curKeyInfo = new Array(4);
            }
        }
        return commandInfoList;
    },
    /**
     * 获取按键精灵命令代码片段
     *
     * @returns {Object} [{name, format, description, case}]
     */
    getAjjlCommandSnippets() {
        const commandInfoList = this.getAjjlCommandInfoList();
        let commandSnippets = {};
        let paramReg = new RegExp(/\{((?!\}).)*\}/);
        let positionReg = new RegExp(/…/);
        commandInfoList.forEach(commandInfoObj => {
            // 处理输出格式
            let bodyFormat = [];
            if (commandInfoObj["format"] !== undefined) {
                let tabNum = 1;
                let formatList = commandInfoObj["format"].split("\n");
                for (let formatNum = 0; formatNum < formatList.length; formatNum++) {
                    if (paramReg.test(formatList[formatNum])) {
                        formatList[formatNum] = formatList[formatNum].replace(paramReg, function() { return "$" + tabNum++; });
                        formatNum--;
                    } else if (positionReg.test(formatList[formatNum])) {
                        formatList[formatNum] = formatList[formatNum].replace(positionReg, function() { return "\t$" + tabNum++; });
                        formatNum--;
                    } else {
                        bodyFormat.push(formatList[formatNum]);
                    }
                }
            } else {
                bodyFormat.push(commandInfoObj["name"]);
            }

            // 添加到对象中
            let commandFormat = bodyFormat[0] !== commandInfoObj["name"] ? `格式：${commandInfoObj["format"]}\n` : ``;
            let commandCase = commandInfoObj["case"] !== undefined ? `\n举例：${commandInfoObj["case"]}` : ``;
            commandSnippets[commandInfoObj["name"]] = {
                "prefix": commandInfoObj["name"],
                "body": bodyFormat,
                "description": `${commandFormat}解释：${commandInfoObj["description"]}${commandCase}`
            };
        });
        return commandSnippets;
    }
};

module.exports = AjjlDatas;